package com.yanggu.sa_token.sso_server_demo.controller;

import cn.dev33.satoken.config.SaSsoConfig;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.sign.SaSignUtil;
import cn.dev33.satoken.sso.SaSsoProcessor;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.dtflys.forest.Forest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Sa-Token-SSO Server端 Controller
 */
@RestController
@RequestMapping("/sso")
public class SsoServerController {

    /**
     * SSO-Server：统一认证地址
     */
    @RequestMapping("/auth")
    public Object ssoAuth() {
        SaRequest req = SaHolder.getRequest();
        //重定向到home页面
        if (req.isPath("/sso/auth") && !req.hasParam("redirect") && StpUtil.isLogin()) {
            return SaHolder.getResponse().redirect("/home");
        }
        return SaSsoProcessor.instance.ssoAuth();
    }

    /**
     * SSO-Server：RestAPI 登录接口
     */
    @RequestMapping("/doLogin")
    public Object ssoDoLogin() {
        return SaSsoProcessor.instance.ssoDoLogin();
    }

    /**
     * SSO-Server：校验ticket 获取账号id
     */
    @RequestMapping("/checkTicket")
    public Object ssoCheckTicket() {
        return SaSsoProcessor.instance.ssoCheckTicket();
    }

    /**
     * SSO-Server：单点注销
     */
    @RequestMapping("/signout")
    public Object ssoSignout() {
        return SaSsoProcessor.instance.ssoSignout();
    }

    // 示例：获取数据接口（用于在模式三下，为 client 端开放拉取数据的接口）
    @RequestMapping("/getData")
    public SaResult getData(String apiType, String loginId) {
        System.out.println("---------------- 获取数据 ----------------");
        System.out.println("apiType=" + apiType);
        System.out.println("loginId=" + loginId);

        // 校验签名：只有拥有正确秘钥发起的请求才能通过校验
        SaSignUtil.checkRequest(SaHolder.getRequest());

        // 自定义返回结果（模拟）
        return SaResult.ok()
                .set("id", loginId)
                .set("name", "LinXiaoYu")
                .set("sex", "女")
                .set("age", 18);
    }


    /**
     * 配置SSO相关参数
     */
    @Autowired
    private void configSso(SaSsoConfig sso) {
        // 配置：未登录时返回的View 
        sso.setNotLoginView(() -> {
            String msg = "当前会话在SSO-Server端尚未登录，请先访问"
                    + "<a href='/sso/doLogin?name=sa&pwd=123456' target='_blank'> doLogin登录 </a>"
                    + "进行登录之后，刷新页面开始授权";
            return msg;
        });

        // 配置：登录处理函数 
        sso.setDoLoginHandle((name, pwd) -> {
            // 此处仅做模拟登录，真实环境应该查询数据进行登录 
            if ("sa".equals(name) && "123456".equals(pwd)) {
                StpUtil.login(10001);
                return SaResult.ok("登录成功！").setData(StpUtil.getTokenValue());
            }
            return SaResult.error("登录失败！");
        });

         //配置 Http 请求处理器 （在模式三的单点注销功能下用到，如不需要可以注释掉）
        sso.setSendHttp(url -> {
            try {
                // 发起 http 请求
                System.out.println("------ 发起请求：" + url);
                return Forest.get(url).executeAsString();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
    }

}
